package com.lynn.common.utils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Build;
import android.provider.Settings;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Display;
import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;

/**
 * DESC:屏幕工具类
 * TIME:2019-06-24
 */
public class ScreenUtil {

    private ScreenUtil() {
    }


///////////////////////////////////////////////////////////////////////////
// dp sp px 相互转换
///////////////////////////////////////////////////////////////////////////


    public static DisplayMetrics getDM(Context context) {
        return context.getResources().getDisplayMetrics();
    }


    public static float getDensity(Context context) {
        return getDM(context).density;
    }

    public static float getDensity(Activity activity) {
        //屏幕dpi
        DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.density;
    }


    public static float getScaledDensity(Context context) {
        return getDM(context).scaledDensity;
    }


    /**
     * 将px值转换为dip或dp值，保证尺寸大小不变
     *
     * @param pxValue （DisplayMetrics类中属性density）
     */
    public static float px2dp(Context context, float pxValue) {
        return pxValue / getDensity(context) + 0.5f;
    }

    /**
     * 将dip或dp值转换为px值，保证尺寸大小不变
     *
     * @param dipValue （DisplayMetrics类中属性density）
     */

    public static float dp2px(Context context, float dipValue) {
        return dipValue * getDensity(context) + 0.5f;
    }


    /**
     * 将px值转换为sp值，保证文字大小不变
     *
     * @param pxValue （DisplayMetrics类中属性scaledDensity）
     */

    public static float px2sp(Context context, float pxValue) {
        return pxValue / getScaledDensity(context) + 0.5f;
    }

    /**
     * 将sp值转换为px值，保证文字大小不变
     *
     * @param spValue （DisplayMetrics类中属性scaledDensity）
     */

    public static float sp2px(Context context, float spValue) {
        return spValue * getScaledDensity(context) + 0.5f;
    }

///////////////////////////////////////////////////////////////////////////
// 将不同单位（如dp、sp等）转换为像素单位(px)
///////////////////////////////////////////////////////////////////////////
    public static float dpUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_DIP);
    }

    public static float pxUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_PX);
    }

    public static float spUnit(Context context, float value) {
        return unit(context, value, TypedValue.COMPLEX_UNIT_SP);
    }

    /**
     *
     * @param value 数值
     * @param unit  单位
     * @return
     */
    private static float unit(Context context, float value, int unit) {
        return TypedValue.applyDimension(unit, value, getDM(context));
    }

///////////////////////////////////////////////////////////////////////////
// 屏幕宽高
///////////////////////////////////////////////////////////////////////////


    public static int getScreenW(Context context) {
        return context.getResources().getDisplayMetrics().widthPixels;
    }

    public static int getScreenH(Context context) {
        return context.getResources().getDisplayMetrics().heightPixels;
    }


    /**
     * 获取屏幕的宽度px
     *
     * @param context 上下文
     * @return 屏幕宽px
     */
    public static int getScreenWidth(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.widthPixels;
    }

    /**
     * 获取屏幕的高度px
     *
     * @param context 上下文
     * @return 屏幕高px
     */
    public static int getScreenHeight(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();// 创建了一张白纸
        windowManager.getDefaultDisplay().getMetrics(outMetrics);// 给白纸设置宽高
        return outMetrics.heightPixels;
    }

    /**
     * 获取屏幕的真实高低 即包含底部虚拟导航栏
     *
     * @param context
     * @return
     */
    public static int getScreenRealHeight(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(dm);
        } else {
            display.getMetrics(dm);
        }
        return dm.heightPixels;
    }

    /**
     * 横屏时
     *
     * @param context
     * @return
     */
    public static int getScreenRealWidth(Context context) {
        WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            display.getRealMetrics(dm);
        } else {
            display.getMetrics(dm);
        }
        return dm.widthPixels;
    }


///////////////////////////////////////////////////////////////////////////
//  状态栏 & 导航栏
///////////////////////////////////////////////////////////////////////////

    private static final int INVALID_VAL = -1;
    private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
    private static final String STATUS_BAR_HEIGHT_RES_NAME = "status_bar_height";


    /**
     * 透明状态栏
     * 需要设置的xml中增加属性：
     * android:clipToPadding="true"
     * android:fitsSystemWindows="true"
     */
    public static void setStatusTranslucent(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
    }

    /**
     * 透明导航栏
     *
     * @param activity
     */
    public static void setNavigationTranslucent(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明导航栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }

    /**
     * 透明状态栏和透明导航栏
     *
     * @param activity
     */
    public static void setTranslucent(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            //透明状态栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            //透明导航栏
            activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
        }
    }


    /**
     * 计算状态栏高度
     *
     * @return 状态栏高度
     */
    public static int getStatusBarHeight() {
        return getInternalDimensionSize(Resources.getSystem(), STATUS_BAR_HEIGHT_RES_NAME);
    }

    private static int getInternalDimensionSize(Resources res, String key) {
        int result = 0;
        int resourceId = res.getIdentifier(key, "dimen", "android");
        if (resourceId > 0) {
            result = res.getDimensionPixelSize(resourceId);
        }
        return result;
    }

    public static int getStatusBarHeight(Context context) {
        int result = 0;
        int resourceId = context.getResources().getIdentifier(STATUS_BAR_HEIGHT_RES_NAME, "dimen", "android");
        if (resourceId > 0) {
            result = context.getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }


    /**
     * 获取ActionBar高度
     *
     * @param activity activity
     * @return ActionBar高度
     */
    public static int getActionBarHeight(Activity activity) {
        TypedValue tv = new TypedValue();
        if (activity.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) {
            return TypedValue.complexToDimensionPixelSize(tv.data, activity.getResources().getDisplayMetrics());
        }
        return 0;
    }


    /**
     * 设置状态栏颜色
     * @param activity
     * @param statusColor
     */
    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public static void compat(Activity activity, int statusColor) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            if (statusColor != INVALID_VAL) {
                activity.getWindow().setStatusBarColor(statusColor);
            }
            return;
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
            int color = COLOR_DEFAULT;
            ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
            if (statusColor != INVALID_VAL) {
                color = statusColor;
            }
            View statusBarView = contentView.getChildAt(0);
            //改变颜色时避免重复添加statusBarView
            if (statusBarView != null && statusBarView.getMeasuredHeight() == getStatusBarHeight(activity)) {
                statusBarView.setBackgroundColor(color);
                return;
            }
            statusBarView = new View(activity);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
                    getStatusBarHeight(activity));
            statusBarView.setBackgroundColor(color);
            contentView.addView(statusBarView, lp);
        }

    }

    public static void compat(Activity activity) {
        compat(activity, INVALID_VAL);
    }


///////////////////////////////////////////////////////////////////////////
// 通知栏
///////////////////////////////////////////////////////////////////////////

//    /**
//     * 显示通知栏
//     * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
//     *
//     * @param context        上下文
//     * @param isSettingPanel {@code true}: 打开设置<br>{@code false}: 打开通知
//     */
//    public static void showNotificationBar(Context context, boolean isSettingPanel) {
//        String methodName = (Build.VERSION.SDK_INT <= 16) ? "expand"
//                : (isSettingPanel ? "expandSettingsPanel" : "expandNotificationsPanel");
//        invokePanels(context, methodName);
//    }
//
//    /**
//     * 隐藏通知栏
//     * <p>需添加权限 {@code <uses-permission android:name="android.permission.EXPAND_STATUS_BAR"/>}</p>
//     *
//     * @param context 上下文
//     */
//    public static void hideNotificationBar(Context context) {
//        String methodName = (Build.VERSION.SDK_INT <= 16) ? "collapse" : "collapsePanels";
//        invokePanels(context, methodName);
//    }
//
//    /**
//     * 反射唤醒通知栏
//     *
//     * @param context    上下文
//     * @param methodName 方法名
//     */
//    private static void invokePanels(Context context, String methodName) {
//        try {
//            Object service = context.getSystemService("statusbar");
//            Class<?> statusBarManager = Class.forName("android.app.StatusBarManager");
//            Method expand = statusBarManager.getMethod(methodName);
//            expand.invoke(service);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }


///////////////////////////////////////////////////////////////////////////
// 屏幕相关：横竖屏
///////////////////////////////////////////////////////////////////////////


    /**
     * 设置全屏
     */
    public static void setFullScreen(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Window window = activity.getWindow();
            window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS
                    | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
            window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                    | View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
            window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
            window.setStatusBarColor(Color.TRANSPARENT);
            window.setNavigationBarColor(Color.TRANSPARENT);
        }
    }

    /**
     * 设置屏幕为横屏
     * <p>还有一种就是在Activity中加属性android:screenOrientation="landscape"</p>
     * <p>不设置Activity的android:configChanges时，切屏会重新调用各个生命周期，切横屏时会执行一次，切竖屏时会执行两次</p>
     * <p>设置Activity的android:configChanges="orientation"时，切屏还是会重新调用各个生命周期，切横、竖屏时只会执行一次</p>
     * <p>设置Activity的android:configChanges="orientation|keyboardHidden|screenSize"（4.0以上必须带最后一个参数）时
     * 切屏不会重新调用各个生命周期，只会执行onConfigurationChanged方法</p>
     *
     * @param activity activity
     */
    public static void setLandscape(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    }

    /**
     * 设置屏幕为竖屏
     *
     * @param activity activity
     */
    public static void setPortrait(Activity activity) {
        activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }

    /**
     * 判断是否横屏
     *
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean isLandscape(Context context) {
        return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;
    }

    /**
     * 判断是否竖屏
     *
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean isPortrait(Context context) {
        return context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
    }


    /**
     * 获取屏幕旋转角度
     *
     * @param activity activity
     * @return 屏幕旋转角度
     */
    public static int getScreenRotation(Activity activity) {
        switch (activity.getWindowManager().getDefaultDisplay().getRotation()) {
            default:
            case Surface.ROTATION_0:
                return 0;
            case Surface.ROTATION_90:
                return 90;
            case Surface.ROTATION_180:
                return 180;
            case Surface.ROTATION_270:
                return 270;
        }
    }


///////////////////////////////////////////////////////////////////////////
// 屏幕相关：截图，常用
///////////////////////////////////////////////////////////////////////////

    /**
     * 获取当前屏幕截图，包含状态栏
     *
     * @param activity activity
     * @return Bitmap
     */
    public static Bitmap captureWithStatusBar(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = Bitmap.createBitmap(bmp, 0, 0, width, height);
        view.destroyDrawingCache();
        return bp;
    }

    /**
     * 获取当前屏幕截图，不包含状态栏
     * <p>需要用到上面获取状态栏高度getStatusBarHeight的方法</p>
     *
     * @param activity activity
     * @return Bitmap
     */
    public static Bitmap captureWithoutStatusBar(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bmp = view.getDrawingCache();
        int statusBarHeight = StatusBarUtil.getStatusBarHeight(activity);
        int width = getScreenWidth(activity);
        int height = getScreenHeight(activity);
        Bitmap bp = Bitmap.createBitmap(bmp, 0, statusBarHeight, width, height - statusBarHeight);
        view.destroyDrawingCache();
        return bp;
    }


///////////////////////////////////////////////////////////////////////////
// 屏幕相关：锁屏
///////////////////////////////////////////////////////////////////////////


    /**
     * 判断是否锁屏
     *
     * @param context 上下文
     * @return {@code true}: 是<br>{@code false}: 否
     */
    public static boolean isScreenLock(Context context) {
        KeyguardManager km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
        if (km == null) return false;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
            return km.isKeyguardLocked();
        else
            return km.inKeyguardRestrictedInputMode();
    }


    /**
     * 设置窗口亮度
     *
     * @param act
     * @param lightMode 0 ～1.0
     */
    public static void setLightMode(Activity act, Float lightMode) {
        Window window = act.getWindow();
        WindowManager.LayoutParams layoutParams = window.getAttributes();
        layoutParams.alpha = lightMode;
        window.setAttributes(layoutParams);
    }


///////////////////////////////////////////////////////////////////////////
// 其他设置
///////////////////////////////////////////////////////////////////////////

    /**
     * 设置进入休眠时长
     * <p>需添加权限 {@code <uses-permission android:name="android.permission.WRITE_SETTINGS" />}</p>
     *
     * @param duration 时长
     */
    public static void setSleepDuration(Context context, int duration) {
        Settings.System.putInt(context.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT, duration);
    }

    /**
     * 获取进入休眠时长
     *
     * @return 进入休眠时长，报错返回-123
     */
    public static int getSleepDuration(Context context) {
        try {
            return Settings.System.getInt(context.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
            return -123;
        }
    }




///////////////////////////////////////////////////////////////////////////
// 适配
//    https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA
///////////////////////////////////////////////////////////////////////////

//    private static float scaledDensity;
//    private static float density;
//    private static float densityDpi;
//
//
//    /**
//     * Reference from: https://mp.weixin.qq.com/s/d9QCoBP6kV9VSWvVldVVwA
//     * 我知道你的意思 依mdpi为例，设计图标的多少xml就写多少 ，实际就是1：1的意思，
//     */
//
//    private static void adaptScreen(final Activity activity,
//
//                                    final float sizeInDp,
//
//                                    final boolean isVerticalSlide) {
//        final DisplayMetrics appDm = BaseApplication.getInstance().getResources().getDisplayMetrics();
//        //每次创建Activity时，这里的值都会是初始值
//        density = appDm.density;
//        scaledDensity = appDm.scaledDensity;
//        densityDpi = appDm.densityDpi;
//
//
//        final DisplayMetrics sysDm = Resources.getSystem().getDisplayMetrics();
//        final DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
//
//        if (isVerticalSlide) {
//
//            activityDm.density = activityDm.widthPixels / sizeInDp;
//
//        } else {
//
//            activityDm.density = activityDm.heightPixels / sizeInDp;
//
//        }
//        Log.d("ScreenUtil", "density=" + density + " appDm.density=" + appDm.density + " appDm.density==" + sysDm.density + " activityDm.density= " + activityDm.density);
//
//        //当activity的density变化时，application的density也会跟着变化，所以这里要使用前面保存的值
//        // activityDm.scaledDensity = activityDm.density * (scaledDensity / density);
//        activityDm.scaledDensity = activityDm.density * (sysDm.scaledDensity / sysDm.density);
//        activityDm.densityDpi = (int) (160 * activityDm.density);
//
//        appDm.density = activityDm.density;
//        appDm.scaledDensity = activityDm.scaledDensity;
//        appDm.densityDpi = activityDm.densityDpi;
//    }
//
//
//
//    /**
//     * Adapt the screen for vertical slide.
//     *
//     * @param designWidthInDp The size of design diagram's width, in dp,
//     *                        <p>
//     *                        e.g. the design diagram width is 720px, in XHDPI device,
//     *                        <p>
//     *                        the designWidthInDp = 720 / 2.
//     */
//
//    public static void adaptScreenPortrait(final Activity activity,
//
//                                           final int designWidthInDp) {
//
//        adaptScreen(activity, designWidthInDp, true);
//
//    }
//
//
//    /**
//     * Adapt the screen for horizontal slide.
//     *
//     * @param designHeightInDp The size of design diagram's height, in dp,
//     *                         <p>
//     *                         e.g. the design diagram height is 1080px, in XXHDPI device,
//     *                         <p>
//     *                         the designHeightInDp = 1080 / 3.
//     */
//
//    public static void adaptScreenLandscape(final Activity activity,
//
//                                            final int designHeightInDp) {
//
//        adaptScreen(activity, designHeightInDp, false);
//
//    }
//
//
//    /**
//     * Cancel adapt the screen.
//     *
//     * @param activity The activity.
//     */
//
//    public static void cancelAdaptScreen(final Activity activity) {
//
//        final DisplayMetrics activityDm = activity.getResources().getDisplayMetrics();
//
//        activityDm.density = density;
//        activityDm.scaledDensity = scaledDensity;
//        activityDm.densityDpi = (int) densityDpi;
//
//    }




}
